package com.jindianjichi.subject.domain.service.impl;
import com.alibaba.fastjson.JSON;
import com.jindianjichi.basic.entity.SubjectInfo;
import com.jindianjichi.basic.entity.SubjectInfoEs;
import com.jindianjichi.basic.entity.SubjectLabel;
import com.jindianjichi.basic.entity.SubjectMapping;
import com.jindianjichi.basic.service.SubejectEsService;
import com.jindianjichi.basic.service.SubjectInfoService;
import com.jindianjichi.basic.service.SubjectLabelService;
import com.jindianjichi.basic.service.SubjectMappingService;
import com.jindianjichi.infra.entity.UserInfo;
import com.jindianjichi.infra.rpc.UserRpc;
import com.jindianjichi.subject.common.entity.PageResult;
import com.jindianjichi.subject.common.enums.IsDeletedEnum;
import com.jindianjichi.subject.common.util.IdWorkerUtil;
import com.jindianjichi.subject.common.util.LoginUtil;
import com.jindianjichi.subject.domain.convert.SubjectInfoConvert;
import com.jindianjichi.subject.domain.entity.SubjectInfoBo;
import com.jindianjichi.subject.domain.entity.SubjectOptionBo;
import com.jindianjichi.subject.domain.handler.subject.SubjectHandlerFactory;
import com.jindianjichi.subject.domain.handler.subject.SubjectInfoHandler;
import com.jindianjichi.subject.domain.redis.RedisUtil;
import com.jindianjichi.subject.domain.service.SubjectInfoDomainService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class subjectInfoDomainServiceImpl implements SubjectInfoDomainService {
    @Resource
    SubjectInfoService subjectInfoService;
    @Resource
    SubjectHandlerFactory subjectHandlerFactory;
    @Resource
    SubjectMappingService subjectMappingService;
    @Resource
    SubjectLabelService subjectLabelService;
    @Resource
    SubejectEsService subejectEsService;
    @Resource
    private UserRpc userRpc;
    @Resource
    private RedisUtil redisUtil;

    private static final String RABK_KEY="subject_rank";


@Override
@Transactional
    public void addSubjectInfo(SubjectInfoBo subjectInfoBo) {
        if (log.isInfoEnabled()){
            log.info("SubjectController.add.SubjectInfoDto:{}", subjectInfoBo);
        }
        SubjectInfo subjectInfo = SubjectInfoConvert.instance.convertInfo(subjectInfoBo);
        subjectInfo.setIsDeleted(IsDeletedEnum.UN_DELETED.getCode());
        subjectInfoService.insert(subjectInfo);
        subjectInfoBo.setId(subjectInfo.getId());
        SubjectInfoHandler handler = subjectHandlerFactory.getHandler(subjectInfoBo.getSubjectType());
        handler.add(subjectInfoBo);
        List<Long> categoryIds = subjectInfoBo.getCategoryIds();
        List<Long> labelIds = subjectInfoBo.getLabelIds();
        List<SubjectMapping> subjectMappingList=new ArrayList<>();
        categoryIds.forEach(categoryId-> {
            for (Long labelId : labelIds) {
                SubjectMapping subjectMapping = new SubjectMapping();
                subjectMapping.setSubjectId(subjectInfoBo.getId());
                subjectMapping.setCategoryId(categoryId);
                subjectMapping.setLabelId(labelId);
                subjectMapping.setIsDeleted(IsDeletedEnum.UN_DELETED.getCode());
                subjectMappingList.add(subjectMapping);
            }
        });

        subjectMappingService.insertBatchs(subjectMappingList);
        //同步到es
       SubjectInfoEs subjectInfoEs =new SubjectInfoEs();
       subjectInfoEs.setDocId(new IdWorkerUtil(1,1,1).nextId());
       subjectInfoEs.setSubjectId(subjectInfo.getId());
       subjectInfoEs.setSubjectName(subjectInfo.getSubjectName());
       subjectInfoEs.setSubjectAnswer(subjectInfoBo.getSubjectAnswer());
       subjectInfoEs.setCreateTime(new Date().getTime());
       subjectInfoEs.setCreateUser("鸡翅");
       subjectInfoEs.setSubjectType(subjectInfo.getSubjectType());
       subejectEsService.insert(subjectInfoEs);
       redisUtil.addScore(RABK_KEY, LoginUtil.getLoginId(),5);
    }

    @Override
    public PageResult<SubjectInfoBo> getSubjectPage(SubjectInfoBo subjectInfoBo) {
        PageResult<SubjectInfoBo> pageResult = new PageResult<>();
        pageResult.setPageNo(subjectInfoBo.getPageNo());
        pageResult.setPageSize(subjectInfoBo.getPageSize());
        int start = (subjectInfoBo.getPageNo() - 1) * subjectInfoBo.getPageSize();
        SubjectInfo subjectInfo = SubjectInfoConvert.instance.convertInfo(subjectInfoBo);
        int count = subjectInfoService.countByCondition(subjectInfo, subjectInfoBo.getCategoryId(), subjectInfoBo.getLabelId());
        if(count<=0){
            return pageResult;
        }
        pageResult.setTotal(count);
        List<SubjectInfo> subjectInfos = subjectInfoService.queryByPage(subjectInfo, start, subjectInfoBo.getPageSize(), subjectInfoBo.getCategoryId(), subjectInfoBo.getLabelId());
        List<SubjectInfoBo> subjectInfoBos = SubjectInfoConvert.instance.convertInfoList(subjectInfos);
        pageResult.setResult(subjectInfoBos);

        return pageResult;
    }

    @Override
    public SubjectInfoBo querySubjectInfo(SubjectInfoBo subjectInfoBO) {
        SubjectInfo subjectInfo = subjectInfoService.queryById(subjectInfoBO.getId());
        SubjectInfoHandler handler = subjectHandlerFactory.getHandler(subjectInfo.getSubjectType());
        SubjectOptionBo subjectOptionBo = handler.queryById(subjectInfo.getId());
        SubjectInfoBo subjectInfoBo = SubjectInfoConvert.instance.convertOptionAndInfoToBo(subjectOptionBo, subjectInfo);
        SubjectMapping subjectMapping = new SubjectMapping();
        subjectMapping.setSubjectId(subjectInfo.getId());
        subjectMapping.setIsDeleted(IsDeletedEnum.UN_DELETED.getCode());
      List<SubjectMapping>mappingList=  subjectMappingService.queryByLabelId(subjectMapping);
        Set<Long> longSet = mappingList.stream().map(SubjectMapping::getLabelId).collect(Collectors.toSet());
        List<SubjectLabel>list=new ArrayList<>();
        for (Long aLong : longSet) {
            SubjectLabel subjectLabel=new SubjectLabel();
            subjectLabel.setId(aLong);
            List<SubjectLabel> subjectLabels = subjectLabelService.queryByConsition(subjectLabel);
            list.add(subjectLabels.get(0));
        }
        List<String> labelNames = list.stream().map(SubjectLabel::getLabelName).collect(Collectors.toList());
        subjectInfoBo.setLabelName(labelNames);


        return subjectInfoBo;
    }

    @Override
    public List<SubjectInfoBo> getContributeList() {
        Set<ZSetOperations.TypedTuple<String>> typedTuples = redisUtil.rankWithScore(RABK_KEY, 0, 8);
        log.info("typedTuples:{}", JSON.toJSONString(typedTuples));
//       List<SubjectInfo>subjectInfoList= subjectInfoService.getContributeList();
       if(CollectionUtils.isEmpty(typedTuples)){
           return Collections.emptyList();
       }
       List<SubjectInfoBo>subjectInfoBoList=new LinkedList<>();
       for (ZSetOperations.TypedTuple typedTuple : typedTuples) {
           SubjectInfoBo subjectInfoBo = new SubjectInfoBo();
           subjectInfoBo.setSubjectCount(typedTuple.getScore().intValue());
           UserInfo userInfo = userRpc.getUserInfo(typedTuple.getValue().toString());
           subjectInfoBo.setCreateUser(userInfo.getNickName());
           subjectInfoBo.setCreateUserAvatar(userInfo.getAvatar());
           subjectInfoBoList.add(subjectInfoBo);
       }
        return subjectInfoBoList;
    }

    @Override
    public PageResult<SubjectInfoEs> getSubjectPageBySearch(SubjectInfoBo subjectInfoBO) {
        SubjectInfoEs subjectInfoEs = new SubjectInfoEs();
        subjectInfoEs.setPageNo(subjectInfoBO.getPageNo());
        subjectInfoEs.setPageSize(subjectInfoBO.getPageSize());
        subjectInfoEs.setKeyWords(subjectInfoBO.getKeyWords());
        return subejectEsService.querySubjectList(subjectInfoEs);

    }
}
